import pandas as pd
import numpy as np
# 预处理模块
from sklearn.preprocessing import Imputer
# 自动生成训练集和测试集的模块
from sklearn.cross_validation import train_test_split
# 预测结果评估模块
from sklearn.metrics import classification_report
# K近邻
from sklearn.neighbors import KNeighborsClassifier
# 决策树
from sklearn.tree import DecisionTreeClassifier
# 高斯朴素bayes
from sklearn.naive_bayes import GaussianNB

# 特征文件列表 标签文件列表
def load_datasets(feature_paths, label_paths):
    # 列数量与特征维度一致
    feature = np.ndarray(shape=(0, 41))
    # 列数量与标签维度一致
    label = np.ndarray(shape=(0, 1))

    # 特征
    for file in feature_paths:
        # delimiter 分隔符 na_values 缺失值 文件不包含表头行
        df = pd.read_table(file, delimiter=',', na_values='?', header=None)
        # 使用平均值补全缺失值
        imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
        # 训练预处理器
        imp.fit(df)
        # 生成预处理结果
        df = imp.transform(df)
        feature = np.concatenate((feature, df))
    # 标签
    for file in label_paths:
        # delimiter 分隔符 na_values 缺失值 文件不包含表头行
        df = pd.read_table(file, header=None)
        label = np.concatenate((label, df))

    label = np.ravel(label)
    return feature, label


if __name__ == '__main__':
    ''' 数据路径 '''
    featurePaths = ['A/A.feature', 'B/B.feature', 'C/C.feature', 'D/D.feature', 'E/E.feature']
    labelPaths = ['A/A.label', 'B/B.label', 'C/C.label', 'D/D.label', 'E/E.label']
    ''' 读入数据  '''
    # 前4个作为 训练集
    x_train, y_train = load_datasets(featurePaths[:4], labelPaths[:4])
    # 最后1个作为 测试集
    x_test, y_test = load_datasets(featurePaths[4:], labelPaths[4:])
    # 设置测试集比例=0 打乱训练数据
    x_train, x_, y_train, y_ = train_test_split(x_train, y_train, test_size=0.0)

    print('Start training knn K近邻')
    knn = KNeighborsClassifier().fit(x_train, y_train)
    print('Training done')
    answer_knn = knn.predict(x_test)
    print('Prediction done')

    print('Start training DT 决策树')
    dt = DecisionTreeClassifier().fit(x_train, y_train)
    print('Training done')
    answer_dt = dt.predict(x_test)
    print('Prediction done')

    print('Start training Bayes 高斯朴素bayes')
    gnb = GaussianNB().fit(x_train, y_train)
    print('Training done')
    answer_gnb = gnb.predict(x_test)
    print('Prediction done')

    print('\n\nThe classification report for knn K近邻:')
    print(classification_report(y_test, answer_knn))
    print('\n\nThe classification report for DT 决策树:')
    print(classification_report(y_test, answer_dt))
    print('\n\nThe classification report for Bayes 高斯朴素bayes:')
    print(classification_report(y_test, answer_gnb))
